%%%-----------------------------------------------------------------------------
%%% @doc
%%% redis client.
%%%
%%% @end
%%%-----------------------------------------------------------------------------
-module(et_eredis).

-behaviour(gen_server).

-define(SERVER, ?MODULE).

%% API Exports 
-export([start_link/1]).

-export([set/2, get/1, delete/1]).

% -export([set_test/1, get_test/1]).

%% gen_server Function Exports
-export([init/1,
		 handle_call/3,
		 handle_cast/2,
		 handle_info/2,
         terminate/2,
		 code_change/3]).

-record(state, {eredis}).

%%%=============================================================================
%%% API
%%%=============================================================================
start_link(EredisOpts) ->
    gen_server:start_link({local, ?SERVER}, ?MODULE, [EredisOpts], []).

set(Key, Value) ->
    gen_server:cast(?SERVER, {set, Key, Value}).
get(Key) ->
    gen_server:call(?SERVER, {get, Key}, infinity).

delete(Key) ->
    gen_server:cast(?SERVER, {del, Key}).    

% set_test(Length) ->
%     Fun = fun() ->
%         lists:foreach(
%             fun(_) -> 
%                 gen_server:call(?SERVER, {set, "IM", [{<<"ip">>, <<"192.168.1.1">>},{<<"port">>, 8083}, {<<"weight">>, 1}]}, infinity)
%             end, lists:seq(1, Length))
%     end,
%     timer:tc(Fun).

% get_test(Length) ->
%     Fun = fun() ->
%         lists:foreach(
%             fun(_) -> 
%                 gen_server:call(?SERVER, {get, "IM"}, infinity)
%             end, lists:seq(1, Length))
%     end,
%     timer:tc(Fun).
    

%%%=============================================================================
%%% gen_server callbacks
%%%=============================================================================

init([EredisOpts]) ->
    Ip = proplists:get_value(ip, EredisOpts),
    Port = proplists:get_value(port, EredisOpts),
    {ok, C} = eredis:start_link(Ip, Port),
    {ok, #state{eredis = C}}.

handle_call({set, Key, Value}, _From, #state{eredis = EredisPid} = State) ->
    eredis:q(EredisPid, ["SET", Key, jsx:encode(Value)]),
    {reply, ok, State};

handle_call({get, Key}, _From, #state{eredis = EredisPid} = State) ->
    Restult = case eredis:q(EredisPid, ["GET", Key]) of
        {ok, undefined} ->
            lager:error("Redis not find key is: ~p data~n", [Key]),
            [];
        {ok, Value} ->
            jsx:decode(Value);
        _ ->
            lager:error("Redis not find key is: ~p data~n", [Key]),
            []
    end,
    {reply, Restult, State};
 
handle_call(_Request, _From, State) ->
    {reply, ok, State}.


handle_cast({del, Key}, #state{eredis = EredisPid} = State) ->
    eredis:q(EredisPid, ["DEL", Key]),
    {noreply, State};   

handle_cast({set, Key, Value}, #state{eredis = EredisPid} = State) ->
    eredis:q(EredisPid, ["SET", Key, jsx:encode(Value)]),
    {noreply, State};

handle_cast(_Msg, State) ->
	{noreply, State}.

handle_info({'DOWN', _MRef, process, _DownPid, _Reason}, State) ->
    {noreply, State};

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

%%%=============================================================================
%%% Internal functions
%%%=============================================================================



